package org.pay.service.impl;

import org.apache.commons.collections.CollectionUtils;
import org.pay.service.BaseService;
import org.springframework.stereotype.Service;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.pay.core.common.constant.MchConstant;
import org.pay.core.common.util.MyLog;
import org.pay.core.entity.*;
import org.pay.core.service.IPayChannelService;
import org.pay.service.dao.mapper.ChannelConfigMapper;
import org.pay.service.dao.mapper.PayChannelMapper;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * @author: yangshancheng
 * @date: 17/9/8
 * @description:
 */
@Service
public class PayChannelServiceImpl extends BaseService implements IPayChannelService {

    private static final MyLog _log = MyLog.getLog(PayChannelServiceImpl.class);

    @Autowired
    private PayChannelMapper payChannelMapper;

    @Autowired
    private ChannelConfigMapper channelConfigMapper;

    @Override
    public int add(PayChannel payChannel) {
        return payChannelMapper.insertSelective(payChannel);
    }

    @Override
    public int update(PayChannel payChannel) {
        return payChannelMapper.updateByPrimaryKeySelective(payChannel);
    }

    @Override
    public PayChannel findById(int id) {
        return payChannelMapper.selectByPrimaryKey(id);
    }

    @Override
    public PayChannel findByChannelId(String channelId) {
        PayChannelExample example = new PayChannelExample();
        PayChannelExample.Criteria criteria = example.createCriteria();
        criteria.andChannelIdEqualTo(channelId);
        criteria.andStatusEqualTo(MchConstant.PUB_YES);
        List<PayChannel> payChannelList = payChannelMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(payChannelList)) return null;
        return payChannelList.get(0);
    }

    @Override
    public PayChannel findByPassageAndChannelId(Integer passageId, String channelId) {
        return findByPassageAndChannelId(passageId, channelId, MchConstant.PUB_YES);
    }

    @Override
    public PayChannel findByPassageAndChannelId(Integer passageId, String channelId, Byte status) {
        PayChannelExample example = new PayChannelExample();
        PayChannelExample.Criteria criteria = example.createCriteria();
        criteria.andChannelIdEqualTo(channelId);
        criteria.andPassageIdEqualTo(passageId);
        if(status != null) criteria.andStatusEqualTo(status);
        List<PayChannel> payChannelList = payChannelMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(payChannelList)) return null;
        return payChannelList.get(0);
    }

    @Override
    public List<PayChannel> select(int offset, int limit, PayChannel payChannel) {
        PayChannelExample example = new PayChannelExample();
        example.setOrderByClause("channel_id ASC, create_time DESC");
        example.setOffset(offset);
        example.setLimit(limit);
        PayChannelExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, payChannel);
        return payChannelMapper.selectByExample(example);
    }

    @Override
    public List<PayChannel> selectByPassageId(Integer passageId, Byte scene) {
        ChannelConfigExample example = new ChannelConfigExample();
        ChannelConfigExample.Criteria criteria = example.createCriteria();
        example.setOrderByClause("scene asc");
        criteria.andStatusEqualTo(MchConstant.PUB_YES);
        // 得到官方支持的渠道列表
        List<ChannelConfig> channelConfigList = channelConfigMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(channelConfigList)) return new LinkedList<>();
        List<String> channelIdList = new LinkedList<>();
        for(ChannelConfig channelConfig : channelConfigList) {
            channelIdList.add(channelConfig.getChannelId());
        }

        PayChannelExample payChannelExample = new PayChannelExample();
        PayChannelExample.Criteria payChannelCriteria = payChannelExample.createCriteria();
        if(passageId != null) payChannelCriteria.andPassageIdEqualTo(passageId);
        if(scene != null) payChannelCriteria.andSceneEqualTo(scene);
        payChannelCriteria.andChannelIdIn(channelIdList);
        // 得到通道已配置的渠道
        List<PayChannel> payChannelList = payChannelMapper.selectByExample(payChannelExample);

        Map<String, PayChannel> payChannelMap = new HashMap<>();
        for(PayChannel payChannel : payChannelList) {
            payChannelMap.put(payChannel.getChannelId(), payChannel);
        }

        // 遍历支持的渠道,如果应用配置了使用应用自身的渠道配置,否则使用官方的配置
        List<PayChannel> retPayChannelList = new LinkedList<>();
        for(ChannelConfig channelConfig : channelConfigList) {
            channelIdList.add(channelConfig.getChannelId());
            PayChannel payChannel = payChannelMap.get(channelConfig.getChannelId());
            if(payChannel == null) {
                payChannel = new PayChannel();
                payChannel.setPassageId(passageId);
                payChannel.setChannelId(channelConfig.getChannelId());
                payChannel.setChannelType(channelConfig.getChannelType());
                payChannel.setScene(channelConfig.getScene());
                payChannel.setState(MchConstant.PUB_NO); // 默认未开通
                payChannel.setParam(channelConfig.getParam());
                payChannel.setRemark(channelConfig.getRemark());
            }
            retPayChannelList.add(payChannel);
        }
        return retPayChannelList;
    }

    @Override
    public List<PayChannel> selectByMch(Long mchId, String channelId) {
        Map param = new HashMap<>();
        param.put("mchId", mchId);
        param.put("channelId", channelId);
        return payChannelMapper.selectByMch(param);
    }

    @Override
    public List<PayChannel> selectByChannelIds(PayChannel payChannel, List<String> channelIds) {
        PayChannelExample example = new PayChannelExample();
        PayChannelExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, payChannel);
        criteria.andChannelIdIn(channelIds);
        return payChannelMapper.selectByExample(example);
    }

    @Override
    public List<PayChannel> selectAll(PayChannel payChannel) {
        PayChannelExample example = new PayChannelExample();
        example.setOrderByClause("channel_mch_id asc");
        PayChannelExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, payChannel);
        return payChannelMapper.selectByExample(example);
    }

    @Override
    public Integer count(PayChannel payChannel) {
        PayChannelExample example = new PayChannelExample();
        PayChannelExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, payChannel);
        return payChannelMapper.countByExample(example);
    }

    void setCriteria(PayChannelExample.Criteria criteria, PayChannel payChannel) {
        if(payChannel != null) {
            if(StringUtils.isNotBlank(payChannel.getChannelId())) criteria.andChannelIdEqualTo(payChannel.getChannelId());
            if(payChannel.getPassageId() != null) criteria.andPassageIdEqualTo(payChannel.getPassageId());
            if(payChannel.getState() != null) criteria.andStatusEqualTo(payChannel.getState());
        }
    }
}
